import {Component, HostListener, Input, OnInit} from '@angular/core';
import TileLayer from 'ol/layer/Tile';
import {XYZ} from 'ol/source';
import {UtilComponent} from '../../interface/util-component.interface';
import Map from 'ol/Map';

declare var document: any;

@Component({
    selector: 'kylin-layer-spy',
    templateUrl: './layer-spy.component.html',
    styleUrls: ['./layer-spy.component.less']
})
export class LayerSpyComponent implements OnInit, UtilComponent {
    // ---------- 接口实现 begin -------------- //
    hasContent = true;
    map: Map;
    target: HTMLElement;

    @Input() set data(val) {
        Object.assign(this, val);
        this.target = this.map.getTargetElement();
    };

    // ---------- 接口实现 end ---------------- // {
    spyLayer: any;
    radius = 75;
    mousePosition: any;

    constructor() {
    }

    ngOnInit() {
        this.spyLayer = new TileLayer({
            source: new XYZ({ // 卫星图
                url: 'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}'
            })
        });
        this.map.addLayer(this.spyLayer);
        this.turnOn();
    }

    turnOn() {
        document.addEventListener('keydown', this.changeRadius);
        this.target.addEventListener('mousemove', this.handleMouseMove);
        this.target.addEventListener('mouseout', this.handleMouseOut);
        // before rendering the layer, do some clipping
        this.spyLayer.on('precompose', (event) => {
            const ctx = event.context;
            const pixelRatio = event.frameState.pixelRatio;
            ctx.save();
            ctx.beginPath();
            if (this.mousePosition) {
                // only show a circle around the mouse
                ctx.arc(this.mousePosition[0] * pixelRatio, this.mousePosition[1] * pixelRatio,
                    this.radius * pixelRatio, 0, 2 * Math.PI);
                ctx.lineWidth = 5 * pixelRatio;
                ctx.strokeStyle = 'rgba(0,0,0,0.5)';
                ctx.stroke();
            }
            ctx.clip();
        });
        // after rendering the layer, restore the canvas context
        this.spyLayer.on('postcompose', (event) => {
            const ctx = event.context;
            ctx.restore();
        });
    }

    changeRadius = (evt: any) => {
        if (evt.which === 38) {
            this.radius = Math.min(this.radius + 5, 150);
            this.map.render();
            evt.preventDefault();
        } else if (evt.which === 40) {
            this.radius = Math.max(this.radius - 5, 25);
            this.map.render();
            evt.preventDefault();
        }
    }

    handleMouseMove = (event) => {
        this.mousePosition = this.map.getEventPixel(event);
        this.map.render();
    }

    handleMouseOut = (event) => {
        this.mousePosition = null;
        this.map.render();
    }

    turnOff() {
        this.target.removeEventListener('mousemove', this.handleMouseMove);
        this.target.removeEventListener('mouseout', this.handleMouseOut);
        this.map.removeLayer(this.spyLayer);
        document.removeEventListener('keydown', this.changeRadius);
    }

    cancel(options?: any): any {
        this.turnOff();
    }

}
